package se.devoteam.nexus.ldap;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.concurrent.locks.ReentrantLock;

import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import se.devoteam.nexus.ldap.model.Configuration;
import se.devoteam.nexus.ldap.model.io.xpp3.LDAPConfigurationXpp3Reader;

/**
 * @author Anders Hammar
 */
@Component(role = LdapConfigurationManager.class)
public class DefaultLdapConfigurationManager extends AbstractLogEnabled implements LdapConfigurationManager {

	@org.codehaus.plexus.component.annotations.Configuration(value = "${ldap-xml-file}")
	private File ldapConfiguration;

	/**
	 * This will hold the current configuration in memory, to reload, will need
	 * to set this to null
	 */
	private Configuration configuration = null;

	private ReentrantLock lock = new ReentrantLock();

	public String getUrl() {
		return getConfiguration().getUrl();
	}

	public String getPrincipalPrefix() {
		return getConfiguration().getPrincipalPrefix();
	}

	public String getPrincipalSuffix() {
		return getConfiguration().getPrincipalSuffix();
	}

	public void clearCache() {
		// Just to make sure we aren't fiddling w/ save/load process
		lock.lock();
		this.configuration = null;
		lock.unlock();
	}

	private Configuration getConfiguration() {
		if (this.configuration != null) {
			return this.configuration;
		}

		this.lock.lock();

		Reader fr = null;
		try {
			FileInputStream is = new FileInputStream(ldapConfiguration);
			LDAPConfigurationXpp3Reader reader = new LDAPConfigurationXpp3Reader();
			fr = new InputStreamReader(is);

			this.configuration = reader.read(fr);
		} catch (FileNotFoundException e) {
			getLogger().error("Configuration file not found", e);
		} catch (IOException e) {
			getLogger().error("IOException while retrieving configuration file", e);
		} catch (XmlPullParserException e) {
			getLogger().error("Invalid XML Configuration", e);
		} finally {
			if (fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					// just closing if open
				}
			}

			lock.unlock();
		}

		return this.configuration;
	}
}
